package wangwenjun.phase3.executor.unchecked;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import util.ThreadUtil;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

/**
 * @author ChangLiang
 * @date 2020/6/23
 */
@Slf4j
public class UncheckedExceptionTestV1 {

    @Test
    @DisplayName("test uncaughtExceptionHandler")
    public void test() throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10, new MyThreadFactory());
        IntStream.range(0, 10).boxed().forEach(i -> executorService.execute(() -> {
            // 让 10 threads全部启动 防止线程被复用
            ThreadUtil.sleepForSeconds(2);
            if (i % 2 == 0) {
                int j = 1 / 0;
            } else {
                log.info(" i = " + i);
            }
        }));
        executorService.shutdown();
        executorService.awaitTermination(10, TimeUnit.MINUTES);
        log.warn("test#finish");
    }

    private static class MyThreadFactory implements ThreadFactory {

        private final static AtomicInteger SEQ = new AtomicInteger();

        @Override
        public Thread newThread(Runnable r) {
            Thread thread = new Thread(r);
            thread.setName("my-thread-factory-thread-" + SEQ.getAndIncrement());
            thread.setUncaughtExceptionHandler((t, cause) -> {
                // 这种方法无法获取到runnable中的值 i
                log.error("thread:{} execute failed", t.getName());
                log.error(ThreadUtil.exceptionToString(cause));
            });
            return thread;
        }
    }
}
